import json
import signal
import sys
from multiprocessing import Process

from operation_db import *
from socket import *

# 全局变量
HOST = '0.0.0.0'
PORT = 8000
ADDR = (HOST, PORT)

# 创建数据库连接对象
db = Database()


def do_register(c, data):
    """
        处理注册
    :param c: 客户端连接对象
    :param data: 收到客户端报文
    :return: void
    """
    tmp = data.split(' ')
    name = tmp[1]
    passwd = tmp[2]

    if db.register(name, passwd):
        c.send(b'OK')
    else:
        c.send(b'FAIL')


def do_login(c, data):
    """
        处理请求
    :param c: 客户端连接对象
    :param data: 收到客户端的报文
    :return: void
    """
    tmp = data.split(' ')
    name = tmp[1]
    passwd = tmp[2]
    if db.login(name, passwd):
        c.send(b'OK')
    else:
        c.send(b'FAIL')


def do_query(c, data):
    """
        查询单词
    :param c: 客户端连接对象
    :param data: 收到客户端的报文
    :return: 单词解析
    """
    tmp = data.split(' ')
    word = tmp[1]
    name = tmp[2]
    means = db.query(word)
    if means:
        db.insert_history(name, word)
        c.send(('%s:%s' % (word, means)).encode())
    else:
        c.send('没有找到该单词'.encode())


def do_history(c, data):
    """
        查询用户历史单词查询
    :param c: 客户端连接
    :param data: 收到客户端的报文
    :return: void
    """
    tmp = data.split(' ')
    name = tmp[1]
    name_word_tuple_list = db.history(name)
    history_words = json.dumps(name_word_tuple_list)
    c.send(history_words.encode())



def do_request(c):
    """
        处理客户端请求
    :param c: 客户端连接对象
    :param db: 数据库连接对象
    :return: void
    """
    # 生成游标
    db.create_cursor()
    while True:
        # 等待接收客户端发送数据
        data = c.recv(1024).decode()
        print(c.getpeername(), ':', data)
        if not data or data[0] == 'E':
            c.close()
            sys.exit('客户端退出')
        elif data[0] == 'R':
            do_register(c, data)
        elif data[0] == 'L':
            do_login(c, data)
        elif data[0] == 'Q':
            do_query(c, data)
        elif data[0] == 'H':
            do_history(c,data)


def main():
    # 创建tcp套接字
    s = socket()
    # 频繁重启，快速是否端口号
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    s.bind(ADDR)
    s.listen(5)

    # 处理僵尸进程
    # signal.signal(signal.SIGINT, signal.SIG_IGN)
    """
        SIGABRT
    SIGFPE
    SIGILL
    SIGINT
    SIGSEGV
    SIGTERM
    """
    # 等待客户端连接
    print('Listen the port 8000')
    while True:
        try:
            c, addr = s.accept()
            print('Connect from', addr)
        except KeyboardInterrupt:
            s.close()
            db.close()
            sys.exit('服务器退出')

        except Exception as e:
            print(e)
            continue

        process = Process(target=do_request, args=(c,))
        # 分支线程随主线程退出
        process.daemon = True
        process.start()


if __name__ == "__main__":
    main()
